package cfca.seal.mananger;

import cfca.itool.util.StringUtil;
import cfca.sadk.algorithm.common.PKIException;
import cfca.sadk.util.CertUtil;
import cfca.sadk.x509.certificate.X509Cert;
import cfca.seal.exception.CodeException;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TrustCertManager
{
  private static final Logger log = LoggerFactory.getLogger("web_sys");
  public static String trustCertPath = "";
  private static Map<String, X509Cert> trustCertDNMap = new ConcurrentHashMap();
  public static TrustCertManager instance = new TrustCertManager();

  public void init() throws CodeException {
    synchronized (this) {
      if (StringUtil.isEmpty(trustCertPath)) {
        throw new CodeException("C5001", "信任证书路径不存在");
      }
      trustCertDNMap.clear();
      File p7bFile = new File(trustCertPath);
      if (p7bFile.exists()) {
        X509Cert[] trustCerts = null;
        try {
          trustCerts = CertUtil.parseP7B(trustCertPath);
          for (int i = 0; i < trustCerts.length; i++) {
            X509Cert cert = trustCerts[i];
            trustCertDNMap.put(cert.getSubject(), trustCerts[i]);
          }
          log.info("信任证书管理容器初始始化成功:" + trustCertDNMap.size());
        } catch (PKIException e) {
          throw new CodeException("C5002", "信任证书容器初始化失败");
        }
      }
    }
  }

  public void refresh() throws CodeException {
    init();
  }

  public X509Cert getTrustCertByDn(String dn) {
    return (X509Cert)trustCertDNMap.get(dn);
  }

  public void importTrustCert(String dn, X509Cert cert) throws CodeException {
    synchronized (this) {
      boolean isCA = false;
      try {
        isCA = CertUtil.isCACert(cert);
      } catch (PKIException e) {
        throw new CodeException("C5004", "检查信任证书类型失败");
      }

      if (!isCA) {
        throw new CodeException("C5003", "信任证书必须是CA证书");
      }

      if (trustCertDNMap.containsKey(dn)) {
        throw new CodeException("C5005", "添加的的信任证书已经存在");
      }

      trustCertDNMap.put(dn, cert);

      log.info("信任证书管理容器添加新的信任证书成功" + dn);
      saveToFile();
    }
  }

  public void deleteTrustCert(String dn) throws CodeException {
    synchronized (this) {
      trustCertDNMap.remove(dn);
      log.info("信任证书管理容器删除信任证书成功" + dn);
      saveToFile();
    }
  }

  private void saveToFile() throws CodeException
  {
    try {
      int size = trustCertDNMap.size();
      if (size <= 0) {
        File file = new File(trustCertPath);
        if (file.exists())
          file.delete();
      }
      else {
        X509Cert[] certs = new X509Cert[size];
        trustCertDNMap.values().toArray(certs);
        CertUtil.generateP7BFile(certs, trustCertPath);
      }
    } catch (Exception ex) {
      throw new CodeException("C5006", "信任证书容器更新发生异常");
    }
  }

  public List<X509Cert> getTrustCertList() {
    ArrayList list = new ArrayList();
    for (String key : trustCertDNMap.keySet()) {
      list.add(trustCertDNMap.get(key));
    }
    return list;
  }

  public boolean checkTrustCertExist(String dn) {
    return trustCertDNMap.containsKey(dn);
  }
}